//
// Created by 黄扬航 on 2023/9/30.
//

#ifndef SERVER_SERVER_H
#define SERVER_SERVER_H
#include <iostream>
#include <string>
#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <winsock2.h>
#include <algorithm>
#include <unistd.h>
#include<queue>
#include <ctime>
#include<vector>
#include "CheckType.h"
#include <windows.h>
#include<WS2tcpip.h>
#include<atomic>
#pragma comment(lib, "ws2_32.lib")
const int MAX_CLIENTS = 5000;
struct message
{
    message(){}
    message(std::string Message_in,int SquenceId_in,int MessageFrom_in,int MessageTo_in):
    Message(Message_in),
    SquenceId(SquenceId_in),
    MessageFrom(MessageFrom_in),
    MessageTo(MessageTo_in){};


    std::string Message;
    int SquenceId;   //服务端决定，递增。
    int MessageFrom;
    int MessageTo;
    bool IsSafe = false;
    time_t time;
};
struct ClientInfo{
    ClientInfo(SOCKET ClientSocket_in,sockaddr_in ClientAddr_in,int clientId):
    ClientSocket(ClientSocket_in),
    ClientID(clientId),
    ClientAddr(ClientAddr_in){};


    SOCKET ClientSocket;
    sockaddr_in ClientAddr;
    int ClientID;
    std::vector<message> Message;
    int CurrentMessageID = 0;
    int CurrentMessagePtr = 0;
};
class Server
{
private:
    SOCKET ServerSocket;
    sockaddr_in ServerAddr;
    int Recevtimeout = 3000; //3s
    int CurrentId = 0;
    message DealNewMessage(SOCKET client,int messagetype);
    int AcceptShortClient(SOCKET client);
public:
    Server()
    {
        ServerSocket = INVALID_SOCKET;
    }
    bool ServerInit();
    struct timeval timeout{3,0};
    std::vector<ClientInfo> ClientItems;
    void AcceptShortClientThread(SOCKET client);
    int NotifiyClient(SOCKET Client, int NoticeType,message Message);
    int SendMessageTo(SOCKET Client,std::string Message);
    int AcceptClient();
    ClientInfo *FindSocketInfo(SOCKET client);
    ClientInfo *FindSocketInfo(int clientID);
    int CheckSendACK(SOCKET TempCLient,int message_length,int ACK_Type,message & Message);
    void StartAcceptClient();
    int SetTimeOut(SOCKET &socket);
    void StartAcceptShortClientThread(SOCKET client);
    std::atomic<bool> m_isRunning=true;
    void StopAcceptShortClientThread();
};
#endif //SERVER_SERVER_H
